﻿using System.Windows;

using Game.Common;
using Game.Level;
using Game.Map;

namespace Game.Command.Internal
{
    class AttackFormula
    {
        readonly AttackParameters _Parameters;
        readonly IGameMapView _GameMap;
        readonly GameLevels _GameLevels;
        
        public AttackFormula(
            IGameMapView gameMap,
            GameLevels gameLevels)
        {
            _Parameters = new AttackParameters();
            _GameMap = gameMap;
            _GameLevels = gameLevels;
        }

        public IGameMapView GameMap
        {
            get { return _GameMap; }
        }

        public GameLevels GameLevels
        {
            get { return _GameLevels; }
        }

        protected double strength_experience(int experience)
        {
            double e = (experience < 0) ? 0 : experience;
            return 
                (e / GameParameters.MaxUnitExperience) * 2.875 /
                _Parameters.ExperienceDivisorAttack;
        }
        
        protected double strength_damage ( int damage )
        {
            return 1 - (2.0 * (damage) / 300.0);
        }
        
        protected double strength_attackbonus ( int abonus )
        {
            double a = abonus;
            return a/8;
        }
        
        protected double strength_hemming (double ax, 
                                           double ay, 
                                           Point point )
        {
            double hemm = 0;
            const int sidenum = 6;
            
            var direc = new GameDirection();
            for ( int i = 0; i < sidenum-1; i++) 
            {
                direc = direc.Next();
                
                IMapField field = _GameMap.Fields[point];
                if ( CheckHemming(field, direc))
                {
                    hemm += getHemmingFactor(i);
                }
            }
            
            return  hemm + 1;
        }
        
        protected double defense_experience ( int experience )
        {
            double e = (experience < 0) ? 0 : experience;
            return 
                (e/GameParameters.MaxUnitExperience * 1.15) / 
                _Parameters.ExperienceDivisorDefense;
        }
        
        protected double defense_defensebonus ( int defensebonus )
        {
            float d = defensebonus;
            return d/8;
        }
        
        public virtual bool CheckHemming ( IMapField origin, GameDirection direc )
        {
            Point nextField = GameDirection.Add(origin.Point, direc);
            if (!_GameMap.Fields.Contains(nextField))
            {
                return false;
            }
            
            IMapField fld = _GameMap.Fields[nextField];
            return AttackUtil.IsAttackPossible(origin, fld );
        }
        
        protected double getHemmingFactor ( int relDir )
        {
            const double  maxHemmingFactor = 1.4;  // = +140% !
            const int sidenum = 6;
            var hemming = new double[]
            { 
                4, 11, 16, 11, 4 
            };
            const double maxHemmingSum = 46;
            relDir  %= 6;
            if ( relDir < 0 )
            {
                relDir += sidenum;
            }
            
            return hemming[relDir]*maxHemmingFactor/maxHemmingSum;
        }
        
    }
}
